/**
 * 图片缓存服务
 * 将远程图片下载并缓存到本地，避免重复请求
 */

import { invoke } from '@tauri-apps/api/core';
import { isTauri, getTokenAsync } from './secure-storage';

// 缓存键前缀
const CACHE_KEY_PREFIX = 'image_cache_';
const CACHE_META_PREFIX = 'image_cache_meta_';

// 缓存元数据接口
interface CacheMeta {
  url: string;
  cachedAt: number;
  contentType: string;
  size: number;
}

/**
 * 生成 URL 的哈希值作为缓存键
 */
function hashUrl(url: string): string {
  // 简单的哈希函数
  let hash = 0;
  for (let i = 0; i < url.length; i++) {
    const char = url.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // 转换为32位整数
  }
  return Math.abs(hash).toString(36);
}

/**
 * 获取缓存的图片路径
 */
async function getCachedImagePath(url: string): Promise<string | null> {
  if (!isTauri()) {
    // 浏览器环境使用 IndexedDB
    return await getCachedImageFromIndexedDB(url);
  }
  
  try {
    const cacheKey = hashUrl(url);
    // 直接使用 Rust 后端读取图片并返回 base64 data URI，避免前端文件系统权限问题
    const cachedDataUri = await invoke<string | null>('get_cached_image_data', { cacheKey });
    if (cachedDataUri) {
      return cachedDataUri;
    }
    return null;
  } catch (error) {
    console.warn('获取缓存图片路径失败:', error);
    return null;
  }
}

/**
 * 从 IndexedDB 获取缓存的图片（浏览器环境）
 */
async function getCachedImageFromIndexedDB(url: string): Promise<string | null> {
  return new Promise((resolve) => {
    const request = indexedDB.open('image_cache', 1);
    
    request.onerror = () => {
      console.warn('IndexedDB 打开失败');
      resolve(null);
    };
    
    request.onsuccess = () => {
      const db = request.result;
      const transaction = db.transaction(['images'], 'readonly');
      const store = transaction.objectStore('images');
      const getRequest = store.get(url);
      
      getRequest.onsuccess = () => {
        if (getRequest.result) {
          const blob = getRequest.result.blob;
          const blobUrl = URL.createObjectURL(blob);
          resolve(blobUrl);
        } else {
          resolve(null);
        }
      };
      
      getRequest.onerror = () => {
        resolve(null);
      };
    };
    
    request.onupgradeneeded = (event: any) => {
      const db = event.target.result;
      if (!db.objectStoreNames.contains('images')) {
        db.createObjectStore('images', { keyPath: 'url' });
      }
    };
  });
}

/**
 * 将图片保存到 IndexedDB（浏览器环境）
 */
async function saveImageToIndexedDB(url: string, blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open('image_cache', 1);
    
    request.onerror = () => {
      reject(new Error('IndexedDB 打开失败'));
    };
    
    request.onsuccess = () => {
      const db = request.result;
      const transaction = db.transaction(['images'], 'readwrite');
      const store = transaction.objectStore('images');
      
      const data = {
        url,
        blob,
        cachedAt: Date.now(),
      };
      
      const putRequest = store.put(data);
      
      putRequest.onsuccess = () => {
        const blobUrl = URL.createObjectURL(blob);
        resolve(blobUrl);
      };
      
      putRequest.onerror = () => {
        reject(new Error('保存图片到 IndexedDB 失败'));
      };
    };
    
    request.onupgradeneeded = (event: any) => {
      const db = event.target.result;
      if (!db.objectStoreNames.contains('images')) {
        db.createObjectStore('images', { keyPath: 'url' });
      }
    };
  });
}

/**
 * 下载并缓存图片
 */
async function downloadAndCacheImage(url: string): Promise<string> {
  try {
    console.log('📥 downloadAndCacheImage 开始:', url);
    
    // 获取认证 token
    const token = await getTokenAsync();
    console.log('🔑 Token 状态:', token ? '已获取' : '未获取');
    
    // 构建请求头（图片请求不需要 Content-Type）
    const headers: HeadersInit = {};
    
    // 如果 URL 是 API 端点（需要认证），添加 Authorization header
    // 检查完整 URL 或相对路径
    if (url.includes('/api/upload/') || url.includes('api/upload/')) {
      if (!token) {
        console.error('❌ 下载图片失败: 缺少认证 token', url);
        throw new Error('下载图片失败: 未登录或 token 已过期');
      }
      headers['Authorization'] = `Bearer ${token}`;
      console.log('✅ 已添加 Authorization header');
    }
    
    // 下载图片
    const response = await fetch(url, {
      mode: 'cors',
      credentials: 'omit',
      headers,
    });
    
    if (!response.ok) {
      const errorMsg = `下载图片失败: ${response.status} ${response.statusText}`;
      // 对于 404 错误，使用 warn 而不是 error（文件可能已被删除，这是正常情况）
      if (response.status === 404) {
        console.warn(`⚠️ 图片文件不存在: ${url}`, { status: response.status, statusText: response.statusText });
      } else {
        console.error(errorMsg, { url, status: response.status, statusText: response.statusText });
      }
      throw new Error(errorMsg);
    }
    
    const blob = await response.blob();
    
    if (!isTauri()) {
      // 浏览器环境：保存到 IndexedDB
      return await saveImageToIndexedDB(url, blob);
    }
    
    // Tauri 环境：保存到文件系统，直接使用已有的 base64 数据
    const cacheKey = hashUrl(url);
    const contentType = response.headers.get('content-type') || 'image/jpeg';
    
    // 将 Blob 转换为 base64 data URI（包含前缀）
    const base64DataUri = await new Promise<string>((resolve, reject) => {
      const reader = new FileReader();
      reader.onloadend = () => {
        resolve(reader.result as string);
      };
      reader.onerror = reject;
      reader.readAsDataURL(blob);
    });
    
    // 保存到 Tauri 文件系统（用于持久化缓存）
    const base64Data = base64DataUri.split(',')[1] || base64DataUri;
    await invoke<string>('cache_image', {
      cacheKey,
      base64Data: base64Data,
      contentType,
    });
    
    // 直接返回 base64 data URI（不需要读取文件，因为我们已经有了）
    return base64DataUri;
  } catch (error) {
    console.error('下载并缓存图片失败:', error);
    throw error;
  }
}

/**
 * 将 Blob 转换为 base64
 */
function blobToBase64(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => {
      const base64 = reader.result as string;
      // 移除 data URI 前缀
      const base64Data = base64.split(',')[1] || base64;
      resolve(base64Data);
    };
    reader.onerror = reject;
    reader.readAsDataURL(blob);
  });
}

/**
 * 获取图片 URL（优先使用缓存）
 * @param url 图片URL
 * @param fallbackToEmpty 如果下载失败，是否返回空字符串而不是抛出错误（默认true）
 * @returns 图片URL，如果失败且fallbackToEmpty为true则返回空字符串
 */
export async function getCachedImageUrl(url: string, fallbackToEmpty: boolean = true): Promise<string> {
  if (!url) return '';
  
  // base64 data URI 直接返回
  if (url.startsWith('data:image/')) {
    return url;
  }
  
  // 检查缓存
  const cachedPath = await getCachedImagePath(url);
  if (cachedPath) {
    // cachedPath 已经是转换后的 URL（Tauri 或 blob URL）
    return cachedPath;
  }
  
  // 缓存不存在，下载并缓存
  try {
    const cachedUrl = await downloadAndCacheImage(url);
    return cachedUrl;
  } catch (error: any) {
    // 对于 404 错误，静默处理（文件可能已被删除，这是正常情况）
    if (error?.message?.includes('404') || error?.message?.includes('Not Found')) {
      if (fallbackToEmpty) {
        return '';
      }
      // 如果 fallbackToEmpty 为 false，仍然抛出错误
      throw error;
    }
    
    // 对于其他错误，记录警告
    console.warn('图片缓存失败:', error);
    // 如果设置了fallbackToEmpty，返回空字符串而不是抛出错误
    // 这样调用者可以使用默认头像
    if (fallbackToEmpty) {
      return '';
    }
    // 对于需要认证的 API 端点，如果fallbackToEmpty为false，抛出错误
    if (url.includes('/api/upload/')) {
      throw error;
    }
    // 对于外部图片，如果缓存失败，可以返回原始 URL
    return url;
  }
}

/**
 * 清理图片缓存
 */
export async function clearImageCache(): Promise<void> {
  if (!isTauri()) {
    // 浏览器环境：清理 IndexedDB
    return new Promise((resolve) => {
      const request = indexedDB.deleteDatabase('image_cache');
      request.onsuccess = () => resolve();
      request.onerror = () => resolve(); // 忽略错误
    });
  }
  
  try {
    await invoke('clear_image_cache');
  } catch (error) {
    console.error('清理图片缓存失败:', error);
  }
}

